package de.lns.entities;

import java.nio.FloatBuffer;

import de.lns.entities.ai.Ai;
import de.lns.level.Level;
import de.lns.level.Shapes;
import de.lns.render.Model;
import de.lns.render.Drawable;
import de.lns.render.ModelFactory;
/**
 * 
 * @author Jascha
 *
 */
public abstract class Entity implements Drawable {

	protected double direction = 0.0;
	protected Ai ai;
	protected double scale = 1;
	
	protected double posX;
	protected double posY;
	protected double posZ = 1;
	protected Model model;
	protected static FloatBuffer mesh = ModelFactory.genRectMesh(5, 5);
	protected static FloatBuffer map = ModelFactory.genRectMap();
	// pos x,y,z displays the position of the entity in a mathematical
	// coordinate system
	
	protected static int hashIterator;
	protected int hash;
	protected Shapes hitbox;
	
	// z layer isn't implemented yet
	protected double hitZ=0;
	
	
	public Shapes getHitbox() {
		return hitbox;
	}

	public void setHitbox(Shapes hitbox) {
		this.hitbox = hitbox;
	}
	protected static String texturepath;
	protected static int textureid;
	/**
	 * 
	 * @param posX Xposition of the Entity
	 * @param posY YPosition of the Entity
	 */
	public Entity(double posX, double posY) {
		this.posX = posX;
		this.posY = posY;
		this.model= ModelFactory.genModelSimple(this);
		this.hash = hashIterator++;
	}
	/**
	 * 
	 * @param posX Xposition of the Entity
	 * @param posY YPosition of the Entity
	 * @param posZ Zposition of the Entity
	 */

	public Entity(double posX, double posY, double posZ, double hitZ) {
		this.posX = posX;
		this.posY = posY;
		this.posZ = posZ;
		this.hitZ = hitZ;
		this.model= ModelFactory.genModelSimple(this);
	}

	public double getPosX() {
		return posX;
	}

	/**
	 * 
	 * @param posX The Xposition of the Entity
	 */
	public void setPosX(double posX) {
		this.posX = posX;
	}

	public double getPosY() {
		return posY;
	}

	/**
	 * 
	 * @param posY
	 *            is used to display the Y position of the entity
	 */
	public void setPosY(double posY) {
		this.posY = posY;
	}

	public double getPosZ() {
		return posZ;
	}

	/**
	 * 
	 * @param posZ
	 *            is used to display the ground layer of the entity (the zlayer)
	 */
	public void setPosZ(double posZ) {
		this.posZ = posZ;
	}


	public double getHitZ() {
		return hitZ;
	}

	/**
	 * 
	 * @param hitZ
	 *            is used to display the hitbox in Z-direction
	 */
	public void setHitZ(double hitZ) {
		this.hitZ = hitZ;
	}
	/**
	 * 
	 * @param x how far you want to move in x direction
	 * @param y how far you want to move in y direction
	 * @param z how far you want to move in z direction
	 */
	public void move(double x, double y, double z) {
		this.posX += x;
		this.posY += y;
		this.posZ += z;

	}
	/**
	 * 
	 * @param degrees how far the Entity turns in degrees
	 */
	public void turn(double degrees){
		direction+=degrees;
		if(direction>360){
			direction%=360;
		}
	}
	
	public double getDirection() {
		return direction;
	}

	public void setDirection(double direction) {
		this.direction = direction;
	}

	public Ai getAi() {
		return ai;
	}
	/**
	 * 
	 * @param ai The ai this entity uses
	 */
	public void setAi(Ai ai) {
		this.ai = ai;
	}

	public int getTextureID() {
		return textureid;
	}
	
	/**
	 * Called by Level, each tick this Entity is alive.
	 */
	public abstract void update();
	/**
	 * Called by Level, when this Entity is created.
	 */
	public void create(){
		
	}
	/**
	 * called by Level when this entity is removed
	 */
	public void dispose() {
		
	}
	
	public double getScale(){
		return this.scale;
	}
	
	public void setScale(double scale){
		this.scale=scale;
	}
	
	public Model model(){
		return model;
	}

	public void despawn(){
		Level.removeEntity(this);
	}
	/**
	 * 
	 * @param texturepath The path of the texture of this entity
	 */
	public void setTexturepath(String texturepath){
		this.texturepath = texturepath;
	}
	
	@Override
	public int hashCode(){
		return hash;
	}
}
